package it.uni.bo.monitoring.log;

import it.uni.bo.monitoring.mapping.hibernate.LogData;
import it.uni.bo.monitoring.protocol.server.DataObject;

import java.nio.ByteBuffer;
import java.util.concurrent.BlockingQueue;


import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;


public class LazyInsertLogData extends Thread{

	private SessionFactory factory;
	private BlockingQueue<DataObject> logQueue;
	private Logger l;
	private static final String ERROR_ROLLING_BACK="error rolling back transaction";
	private static final String INFO_INSERT="inserisco in LogData i record";

	public LazyInsertLogData(BlockingQueue<DataObject> logQueue, SessionFactory factory){
		l = Logger.getLogger(this.getClass());
		this.logQueue=logQueue;
		this.factory=factory;
	}

	public synchronized void run() {
		Transaction tx =null;
		Session session = null;
		if(factory!=null)
			while(true){
				try {
					int num=0;
					do{
						DataObject object =logQueue.take();
						logQueue.remove(object);
						if(object!=null){
							if((session==null) || (!session.isOpen()))
								session=factory.openSession();
							if((tx == null) || (!tx.isActive()))
								tx=session.beginTransaction();
							String sequence="",username="",password="",applUrl="",wsNamespace="",operation ="";

								sequence=new String(object.getSeqNumber());
								username=new String(object.getUsername());
								password=new String(object.getPassword());
								applUrl=new String(object.getAppLURL());
								wsNamespace=new String(object.getWSNamespace());
								operation=new String(object.getOperation());

							LogData eq = new LogData(
									object.getSize(),
									Character.forDigit(object.getDirection() & 0xFF, 2),
									String.valueOf(ByteBuffer.wrap(object.getTimestamp()).getLong()),
									new String(object.getSession()),
									sequence,
									username,
									password,
									applUrl,
									wsNamespace,
									operation					
							);
							
							if(object.getParams()!=null)
								eq.setParametersByte(object.getParams());
							session.save(eq);
							num++;
						}
					}while(logQueue.size()>0);

					if (tx != null && tx.isActive())
						tx.commit();
					//l.info(INFO_INSERT +" ("+num+")");

				} catch (InterruptedException e) {
					l.error(e.getMessage());
				} catch (RuntimeException e) {
					if (tx != null && tx.isActive()) {
						try {
							tx.rollback();
						} catch (HibernateException e1) {
							l.error(ERROR_ROLLING_BACK);
						}
						throw e;
					}
				}
				finally{
					if ((session!=null) && (session.isOpen())) 
						session.close(); 
				}
			}
	}
}
